"""
lviewer.tools.events

"""

import wx.lib.newevent
import time
import threading

EventType, EVENT_CODE = wx.lib.newevent.NewCommandEvent()

def process():
    wx.GetApp().ProcessPendingEvents()

class Event( object ):
    ident = 0
    def __init__(self):
        # assign an id
        self.ident = Event.ident
        Event.ident += 1

    def add_listener(self, fn):
        def inner(evt):
            fn(*evt.args, **evt.kwargs)
        wx.GetApp().Bind( EVENT_CODE, inner, id = self.ident )

    def fire(self, *args, **kwargs):
        evt = EventType(id = self.ident, args = args, kwargs = kwargs)
        wx.PostEvent( wx.GetApp(), evt )

    def cancel(self):
        """
        Prevent any existing and future fires() from being
        invoked
        """
        wx.GetApp().Unbind( EVENT_CODE, id = self.ident)

class Repeater( object ):
    """
    An object that ensure that the given fn
    is called every interval seconds
    """
    def __init__(self, interval, fn):
        self.interval = interval
        self.fn = fn
        self.event_out = Event()
        self.event_out.add_listener(fn)
        self.active = True

        self.thread = threading.Thread(target = self.fire)
        self.thread.start()

    def stop(self):
        self.active = False
        self.thread.join()

    def fire(self):
        while self.active:
            time.sleep(self.interval)
            self.event_out.fire()
     

